
#include <event2/event.h>
#include <string.h>
#include <iostream>
#include "ftp_task_base.h"
#include "../util/common_util.h"

void FtpTaskBase::ConnectoPORT() {
	LOGDEBUG("At FtpTaskBase::ConnectoPORT");
	if (cmdTask->ip.empty() || cmdTask->port <= 0 || !cmdTask->base) {
		std::cout << "ConnectPORT failed" << std::endl;
		return;
	}
	if (bev) {
		bufferevent_free(bev);
		bev = 0;
	}
	bev = bufferevent_socket_new(cmdTask->base, -1, BEV_OPT_CLOSE_ON_FREE);
    sockaddr_in sin;
    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(cmdTask->port);
    evutil_inet_pton(AF_INET, cmdTask->ip.c_str(), &sin.sin_addr.s_addr);

	// 将实例对象的回调函数(Read、Write、Event)实现设定为回调函数
	Setcb(bev);

	// 添加数据通道的超时事件
	timeval t = {60, 0};
	bufferevent_set_timeouts(bev, &t, 0);

	// 主动连接客户端
	bufferevent_socket_connect(bev, (sockaddr*)&sin, sizeof(sin));
}

void FtpTaskBase::ClosePORT() {
	if (bev) {
		bufferevent_free(bev);
		bev = 0;
	}
	if (fp) {
		fclose(fp);
		fp = 0;
	}
}

void FtpTaskBase::Setcb(bufferevent *bev) {
	//设置回调函数, 回调函数将调用this指向实例的三个处理函数
	bufferevent_setcb(bev, ReadCb, WriteCb, EventCb, this);
	// 添加监控事件
	bufferevent_enable(bev, EV_READ | EV_WRITE);

}

void FtpTaskBase::Send(const std::string &data) {
	LOGDEBUG("At FtpTaskBase::Send");
	Send(data.c_str(), data.size());
}
void FtpTaskBase::Send(const char *data, size_t datasize) {
	LOGDEBUG("At FtpTaskBase::Send");
	std::cout << data;
	if (datasize == 0) return;
	if (bev) {
		bufferevent_write(bev, data, datasize);
	}
}

void FtpTaskBase::ResCMD(std::string msg) {
	LOGDEBUG("At FtpTaskBase::ResCMD");
	if (!cmdTask || !cmdTask->bev) return;
	std::cout << "ResCMD: " << msg << std::endl;
	if (msg[msg.size() - 1] != '\n') {
		msg += "\r\n";
	}
	bufferevent_write(cmdTask->bev, msg.c_str(), msg.size());
}


void FtpTaskBase::EventCb(bufferevent *bev, short events, void *arg) {
	FtpTaskBase *t = (FtpTaskBase*)arg;
	t->Event(bev, events);
}
void FtpTaskBase::ReadCb(bufferevent *bev, void *arg) {
	FtpTaskBase *t = (FtpTaskBase*)arg;
	t->Read(bev);
}
void FtpTaskBase::WriteCb(bufferevent *bev, void *arg) {
	FtpTaskBase *t = (FtpTaskBase*)arg;
	t->Write(bev);
}


FtpTaskBase::~FtpTaskBase() {
	ClosePORT();
}
